// ==UserScript==
// @name         New Userscript
// @namespace    http://tampermonkey.net/
// @version      2024-11-26
// @description  try to take over the world!
// @author       You
// @match        https://live.bilibili.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=bilibili.com
// @run-at       document-start
// ==/UserScript==
(function () {
    'use strict';

    var wssSubUrl = 'wss://zj-cn-live-comet.chat.bilibili.com:2245/sub'
    var originalWebSocket = WebSocket;
    var wsSub;
    function HookedWebSocket(url, protocols) {
        var socket = new originalWebSocket(url, protocols);
        if (url === wssSubUrl) {
            wsSub = socket;
        }
        return socket;
    }
    HookedWebSocket.prototype = originalWebSocket.prototype;
    unsafeWindow.WebSocket = HookedWebSocket;

    window.addEventListener('load', () =>{
        if(!wsSub){
            console.log('wsSub is null');
            return;
        }
        let originalMessageFuc = wsSub.onmessage;
        wsSub.onmessage = function(event) {
            var objectData = convertToObjectFuc(event.data)
            try{
                if(objectData.body.length >= 1){
                    if(objectData.body[0].cmd == "NOTICE_MSG"){
                        if(objectData.body[0].name != "全区道具抽奖广播样式"){
                            console.log("收到消息:", objectData);
                        }

                    }else{
                        objectData.body[0].forEach((ele)=>{
                            if(!['ONLINE_RANK_COUNT', 'ONLINE_RANK_V2', 'INTERACT_WORD', 'DM_INTERACTION', 'DANMU_MSG', 'LIKE_INFO_V3_UPDATE', 'WATCHED_CHANGE', 'LIKE_INFO_V3_CLICK', 'POPULAR_RANK_CHANGED', 'WIDGET_BANNER', "ENTRY_EFFECT"].includes(ele.cmd)){
                                console.log("收到消息:", ele);
                            }
                        })
                    }
                }
            }catch(e){
                console.log("解析消息失败:", e, objectData);
            }

            if (typeof originalMessageFuc === 'function') {
                originalMessageFuc.call(this, event);
            }
        };
    })

    /* convertToObjectFuc env */
    var wsBinaryHeaderList = [{
        "name": "Header Length",
        "key": "headerLen",
        "bytes": 2,
        "offset": 4,
        "value": 16
    }, {
        "name": "Protocol Version",
        "key": "ver",
        "bytes": 2,
        "offset": 6,
        "value": 1
    }, {
        "name": "Operation",
        "key": "op",
        "bytes": 4,
        "offset": 8,
        "value": 2
    }, {
        "name": "Sequence Id",
        "key": "seq",
        "bytes": 4,
        "offset": 12,
        "value": 1
    }]
     function o_a_getDecoder() {
        return window.TextDecoder ? new window.TextDecoder : {
            decode: function(e) {
                return decodeURIComponent(window.escape(String.fromCharCode.apply(String, new Uint8Array(e))))
            }
        }
    }
    var this_decoder;
    var r_a = {
        "WS_OP_HEARTBEAT": 2,
        "WS_OP_HEARTBEAT_REPLY": 3,
        "WS_OP_MESSAGE": 5,
        "WS_OP_USER_AUTHENTICATION": 7,
        "WS_OP_CONNECT_SUCCESS": 8,
        "WS_PACKAGE_HEADER_TOTAL_LENGTH": 16,
        "WS_PACKAGE_OFFSET": 0,
        "WS_HEADER_OFFSET": 4,
        "WS_VERSION_OFFSET": 6,
        "WS_OPERATION_OFFSET": 8,
        "WS_SEQUENCE_OFFSET": 12,
        "WS_BODY_PROTOCOL_VERSION_NORMAL": 0,
        "WS_BODY_PROTOCOL_VERSION_BROTLI": 3,
        "WS_HEADER_DEFAULT_VERSION": 1,
        "WS_HEADER_DEFAULT_OPERATION": 1,
        "WS_HEADER_DEFAULT_SEQUENCE": 1,
        "WS_AUTH_OK": 0,
        "WS_AUTH_TOKEN_ERROR": -101
    }
    /* convert ArrayBuffer to Object */
    function convertToObjectFuc(e) {
        var t = new DataView(e)
          , i = {
            body: []
        };
        if (i.packetLen = t.getInt32(r_a.WS_PACKAGE_OFFSET),
        wsBinaryHeaderList.forEach((function(e) {
            4 === e.bytes ? i[e.key] = t.getInt32(e.offset) : 2 === e.bytes && (i[e.key] = t.getInt16(e.offset))
        }
        )),
        i.packetLen < e.byteLength && convertToObjectFuc(e.slice(0, i.packetLen)),
        this_decoder || (this_decoder = o_a_getDecoder()),
        !i.op || r_a.WS_OP_MESSAGE !== i.op && i.op !== r_a.WS_OP_CONNECT_SUCCESS)
            i.op && r_a.WS_OP_HEARTBEAT_REPLY === i.op && (i.body = {
                count: t.getInt32(r_a.WS_PACKAGE_HEADER_TOTAL_LENGTH)
            });
        else
            for (var n = r_a.WS_PACKAGE_OFFSET, s = i.packetLen, a = "", l = ""; n < e.byteLength; n += s) {
                s = t.getInt32(n),
                a = t.getInt16(n + r_a.WS_HEADER_OFFSET);
                if (i.ver === r_a.WS_BODY_PROTOCOL_VERSION_NORMAL) {
                    var c = this_decoder.decode(e.slice(n + a, n + s));
                    l = 0 !== c.length ? JSON.parse(c) : null
                } else if (i.ver === r_a.WS_BODY_PROTOCOL_VERSION_BROTLI) {
                    var h = e.slice(n + a, n + s)
                        , u = unsafeWindow.BrotliDecode(new Uint8Array(h));
                    l = convertToObjectFuc(u.buffer).body
                }
                l && i.body.push(l)
            }
        return i
    }
    
})();